package com.liufei1988.java8.string;

import java.lang.reflect.Field;
import java.nio.charset.Charset;

public class StringDemo {

    /**
     * 字面常亮定义String
     */
    public static void hashC(){
        //这里Java会优先在字符串常量池中查找字符串是否存在，如果存在则直接返回字符串的引用地址
        String name="beijing diting robot";
        String name1="beijing diting robot";
        //System.identityHashCode(name) 原始的hashcode，而不是String重载后
        System.out.println("name|"+ name+" - "+System.identityHashCode(name));
        System.out.println("name1|"+ name1+" - "+System.identityHashCode(name1));
    }

    /**
     * new String(String original)定义字符串
     */
    public static void hashC2(){
        //这里Java会优先在字符串常量池中查找字符串是否存在，如果存在则直接返回字符串的引用地址
        String name="beijing diting robot";
        String name1="beijing diting robot";
        //创建新的字符串对象
        String name2=new String("beijing diting robot");
        //System.identityHashCode(name) 原始的hashcode，而不是String重载后
        System.out.println("name|"+ name+" - "+System.identityHashCode(name));
        System.out.println("name1|"+ name1+" - "+System.identityHashCode(name1));
        //打印出的hashcode明显不同，说明name2创建了一个新的字符串对象
        System.out.println("name2|"+ name2+" - "+System.identityHashCode(name2));
    }

    /**
     * 通过反射强制修改String的内容(为了验证需要，在业务环境中不要使用，否则会改变String不可变的规则)
     */
    public static void hashC3(){
        //这里Java会优先在字符串常量池中查找字符串是否存在，如果存在则直接返回字符串的引用地址
        String name="beijing diting robot";
        String name1="beijing diting robot";
        //创建新的字符串对象
        String name2=new String("beijing diting robot");
        System.out.println("before name|"+ name+" - "+System.identityHashCode(name2));
        try{
            Field charsField=String.class.getDeclaredField("value");
            charsField.setAccessible(true);
            char[] object= (char[]) charsField.get(name);
            System.out.println(object.length);
            object[0]='P';//修改字符串第一个字符
        }catch (Exception e){
            e.printStackTrace();
        }
        //System.identityHashCode(name) 原始的hashcode，而不是String重载后
        System.out.println("name|"+ name+" - "+System.identityHashCode(name));
        System.out.println("name1|"+ name1+" - "+System.identityHashCode(name1));
        //name2输出变为Peijing diting robot
        System.out.println("name2|"+ name2+" - "+System.identityHashCode(name2));
    }

    /**
     * 通过反射强制修改String的内容(为了验证需要，在业务环境中不要使用，否则会改变String不可变的规则)
     * 新增new String(char value[])的创建方式
     * hashC3()与hashC4()两个方法的输出结果对比可发现new String(String original) 其实只是创建一个String外壳，内在的char[]其实是共用的，这说明不管你用new String(String original) 创建多少个对象，只要字符串一样，就会共用char[]，真正的堆存储也会共用，避免了浪费；
     *
     * 而new String(char value[])是用了数组拷贝，原因也很简单，数组是你传进来的，为了保证String的不可变属性，只能拷贝，不能复用。
     */
    public static void hashC4(){
        //这里Java会优先在字符串常量池中查找字符串是否存在，如果存在则直接返回字符串的引用地址
        String name="beijing diting robot";
        String name1="beijing diting robot";
        //创建新的字符串对象
        String name2=new String("beijing diting robot");
        String name3=new String(name.toCharArray());
        System.out.println(name3);
        try{
            Field charsField=String.class.getDeclaredField("value");
            charsField.setAccessible(true);
            char[] object= (char[]) charsField.get(name);
            System.out.println(object.length);
            object[0]='G';//修改字符串第一个字符
        }catch (Exception e){
            e.printStackTrace();
        }
        //System.identityHashCode(name) 原始的hashcode，而不是String重载后
        System.out.println("name|"+ name+" - "+System.identityHashCode(name));
        System.out.println("name1|"+ name1+" - "+System.identityHashCode(name1));
        //name2输出变为Peijing diting robot
        System.out.println("name2|"+ name2+" - "+System.identityHashCode(name2));
        //查看name3是否发生变化
        System.out.println("name3|"+ name3+" - "+System.identityHashCode(name3));
    }

    public static void testStartWith(){
        String str="adksfjreigvnkfdvdkjsdkklsfkd";
        System.out.println(str.startsWith("sfj",4));
    }


    public static void main(String[] args) {
        String str=new String();
        String str1=new String("beijingditingjiqirenkejiyouxinaongsi");
        System.out.println(str1.hashCode());

        System.out.println("------------hashC1-------------");
        hashC();
        System.out.println("------------hashC2-------------");
        hashC2();
        System.out.println("------------hashC3-------------");
        hashC3();
        System.out.println("------------hashC4-------------");
        hashC4();
        String s=new String();
        System.out.println(s);

        System.out.println("--------------test charAt(int index): "+str1.charAt(10));
        System.out.println("--------------test codePointAt(int index): "+str1.codePointAt(10));
        System.out.println("--------------test codePointBefore(int index): "+str1.codePointBefore(10));
        System.out.println("--------------test codePointBefore(int index): "+str1.codePointCount(10,12));
        String s1="Z";
        System.out.println(s1.length());
        System.out.println(s1.codePointCount(0,1));

        String aa=new String("ccc".toCharArray());
        String bb=new String("ccc".toCharArray());
        System.out.println(aa.equals(bb));

        testStartWith();
        
        System.out.println(aa.replace("cc","bb"));

        System.out.println(aa.matches("cc"));

    }
}
